home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / PROGENV / ClassTree.C < prev    next >
C/C++ Source or Header  |  1992-07-02  |  14KB  |  616 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "ClassTree.h"
  6.  
  7. #include "ET++.h"
  8. #include "Zoomer.h"
  9. #include "OrdColl.h"
  10. #include "Set.h"
  11. #include "AccessMem.h"
  12. #include "ClassManager.h"
  13. #include "String.h"
  14.  
  15. #include "ClassItem.h"
  16. #include "ProgEnv.h"
  17. #include "EtPeCmdNo.h"
  18. #include "EtPeManager.h"
  19.  
  20. static RGBColor *c1;
  21. static OrdCollection *treeViews= 0;
  22.  
  23. ONEXIT(PeClassTree)
  24. {
  25.     SafeDelete(c1);
  26. }
  27.  
  28. //---- PeClassTreeView ----------------------------------------------------------
  29.  
  30. NewMetaImpl0(PeClassTreeView, TreeView);
  31.  
  32. PeClassTreeView::PeClassTreeView(EvtHandler *eh, Class *root) 
  33.                      : TreeView(eh, eTLLeftRight, eTCDiagonal2)
  34. {
  35.     if (treeViews == 0)
  36.     treeViews= new OrdCollection;
  37.     treeViews->Add(this);
  38.     
  39.     gClassManager->SetupSubclasses();
  40.     classes= new OrdCollection(200);
  41.     InstallTree(root);  
  42.     show= ePeCTShowAll; 
  43.     references= new OrdCollection;
  44. }
  45.  
  46. PeClassTreeView::~PeClassTreeView()
  47. {
  48.     SafeDelete(classes);
  49.     treeViews->RemovePtr(this);
  50.     if (treeViews->Size() == 0)
  51.     SafeDelete(treeViews);
  52.     if (references) {
  53.     references->FreeAll();
  54.     SafeDelete(references);
  55.     }
  56. }
  57.  
  58. VObject *PeClassTreeView::NodeAsVObject(Object *op)
  59. {
  60.     Class *cl= Guard(op, Class);
  61.     VObject *vop= new PeClassItem(cIdClassItem, cl);
  62.     classes->Add(vop);
  63.     return vop;    
  64. }
  65.  
  66. Iterator *PeClassTreeView::MakeChildrenIter(Object *op)
  67. {
  68.     return Guard(op, Class)->SubclassIterator();
  69. }
  70.  
  71. Command *PeClassTreeView::GetNodeSelector(TreeNode *tn, int cl)
  72. {
  73.     VObject *vop= tn->At(0)->FindItem(cIdClassItem);
  74.     if (vop && vop->IsKindOf(PeClassItem) && vop->TestFlag(eClItemCollapsed)) 
  75.     return new PeNameTreeNodeSelector(tn, cl);
  76.     return TreeView::GetNodeSelector(tn, cl);
  77. }
  78.  
  79. void PeClassTreeView::ShowClass(Class *cl)
  80. {
  81.     PeClassItem *ci= FindClassItem(cl);
  82.     if (ci) {
  83.     RevealRect(ci->ContentRect().Expand(100), Point(0, 100));
  84.     SetSelection((VObject*)ci->GetNextHandler());
  85.     UpdateEvent();
  86.     }
  87. }
  88.  
  89. void PeClassTreeView::SetSelection(VObject *vop)
  90. {
  91.     TreeView::SetSelection(vop);
  92.     SynchSelection();
  93. }
  94.  
  95. void PeClassTreeView::SynchSelection()
  96. {
  97.     VObject *sel= GetSelection();
  98.     PeClassItem *cl= 0, *cl2= 0;
  99.     
  100.     if (sel)
  101.     cl= Guard(sel->FindItem(cIdClassItem), PeClassItem);
  102.     if (treeViews && cl) {
  103.     Iter next(treeViews);
  104.     PeClassTreeView *tvp;
  105.     while (tvp= (PeClassTreeView*)next()) {
  106.         VObject *sel2= tvp->GetSelection();
  107.         if (sel2)
  108.         cl2= Guard(sel2->FindItem(cIdClassItem), PeClassItem);
  109.         if (cl2->GetClass() != cl->GetClass())
  110.         tvp->ShowClass(cl->GetClass());
  111.     }
  112.     }
  113. }
  114.  
  115. Class *PeClassTreeView::GetRootClass()
  116. {
  117.     TreeNode *tn= GetTree();
  118.     PeClassItem *cl= Guard(GetTree()->FindItem(cIdClassItem), PeClassItem);
  119.     return cl->GetClass();
  120. }
  121.  
  122. void PeClassTreeView::ShowAllClasses()
  123. {
  124.     show= ePeCTShowAll; 
  125.     classes->ForEach(PeClassItem,ResetFlag)(eClItemCollapsed);
  126.     CalcLayout();
  127.  
  128. void PeClassTreeView::ShowOnlyAbstractClasses()
  129. {
  130.     Iter next(classes);
  131.     PeClassItem *cl;
  132.     show= ePeCTShowAbstract; 
  133.     classes->ForEach(PeClassItem,ResetFlag)(eClItemCollapsed);
  134.     while (cl= (PeClassItem*)next()) 
  135.     if (!cl->GetClass()->IsAbstract())
  136.         cl->SetFlag(eClItemCollapsed);
  137.     CalcLayout();
  138. }
  139.  
  140. void PeClassTreeView::ShowOnlyApplicationClasses()
  141. {
  142.     static char *etsrc= 0;
  143.     Iter next(classes);
  144.     PeClassItem *cl;
  145.     char buf[1024];
  146.     if (etsrc == 0)
  147.     etsrc= strprintf("%s/src", gEtDir);
  148.     int len= strlen(etsrc);
  149.     
  150.     show= ePeCTShowApp; 
  151.     classes->ForEach(PeClassItem,ResetFlag)(eClItemCollapsed);
  152.     while (cl= (PeClassItem*)next()) {
  153.     Class *cp= cl->GetClass();
  154.     if (gEtPeManager->FileOfClass(cp, buf, TRUE)) {
  155.         if (strncmp(etsrc, buf, len) == 0)
  156.         cl->SetFlag(eClItemCollapsed);
  157.     }
  158.     }
  159.     CalcLayout();
  160. }
  161.  
  162. PeCTreeShow PeClassTreeView::Shows()
  163. {
  164.     return show;
  165. }
  166.  
  167. void PeClassTreeView::DoSetupMenu(Menu *menu)
  168. {
  169.     TreeView::DoSetupMenu(menu);
  170.     VObject *sel= GetSelection();
  171.     if (sel) {
  172.     TreeNode *tn= FindTreeNode(sel);
  173.     char *current;
  174.     if (tn->Collapsed())
  175.         current= "Expand";
  176.     else
  177.         current= "Collapse";        
  178.     menu->ReplaceItem(cDOCOLLAPSE, current);
  179.     }    
  180. }
  181.  
  182. Command *PeClassTreeView::DoMenuCommand(int cmd)
  183. {
  184.     VObject *sel= GetSelection();
  185.     PeClassItem *cl= 0;
  186.     
  187.     if (sel)
  188.     cl= Guard(selection->FindItem(cIdClassItem), PeClassItem);
  189.     
  190.     switch (cmd) {
  191.     case cMEMBERS:
  192.     ShowMembers(cl);
  193.     break;
  194.     
  195.     case cCLIENTS:
  196.     ShowAllClients(cl);
  197.     break;
  198.     
  199.     case cSOURCE:
  200.     Control(cPeHierBrowser, cPeShowBrowser, cl->GetClass());
  201.     break;
  202.     
  203.     case cSPAWN:
  204.     Control(cPeHierBrowser, cPeSpawnHier, gClassManager->Find("Object"));
  205.     break;
  206.     
  207.     case cDOCOLLAPSE:
  208.     Collapse(FindTreeNode(selection));
  209.     break;
  210.     
  211.     case cPROMOTE:
  212.     Control(cPeHierBrowser, cPeSpawnHier, cl->GetClass());
  213.     break;
  214.     
  215.     case cTREEVIEW:
  216.     SetLayout(eTLLeftRight);
  217.     break;
  218.  
  219.     case cOUTLINEVIEW:
  220.     SetLayout(eTLIndented);
  221.     break;
  222.  
  223.     default:
  224.     return TreeView::DoMenuCommand(cmd);
  225.     }
  226.     return gNoChanges;
  227. }
  228.  
  229. void PeClassTreeView::Draw(Rectangle r)
  230. {
  231.     if (references) {
  232.     references->ForEach(PeClassReference,Draw)(r);
  233.     }
  234.     TreeView::Draw(r);
  235. }
  236.  
  237. void PeClassTreeView::AddReference(PeClassReference *cr)
  238. {
  239.     references->Add(cr); 
  240.     InvalidateRect(cr->BBox());       
  241. }
  242.  
  243. void PeClassTreeView::RemoveAllReferences()
  244. {
  245.     references->FreeAll();
  246.     references->Empty(0);
  247.     ForceRedraw();
  248. }
  249.  
  250. void PeClassTreeView::OpenTreeNode(TreeNode *tn, bool)
  251. {
  252.     if (references->Size() == 0)
  253.     return;
  254.     Iter next(references);
  255.     VObject *ci= tn->At(0)->FindItem(cIdClassItem);
  256.     if (ci && ci->IsKindOf(PeClassItem)) {
  257.     PeClassReference *cr;
  258.     while (cr= (PeClassReference*)next()) {
  259.         if (cr->Includes((PeClassItem*)ci)) 
  260.         InvalidateRect(cr->BBox()); 
  261.     }      
  262.     }
  263. }
  264.  
  265. //---- PeCollectClassMembers -----------------------------------------------------
  266.  
  267. class PeCollectClassMembers : public AccessMembers {
  268.     Collection *cp;
  269. public:
  270.     PeCollectClassMembers()
  271.     { cp= new OrdCollection; }
  272.     ~PeCollectClassMembers()
  273.     { SafeDelete(cp); }
  274.     void Member(char *, int, int, int, Class *cl, bool, bool)
  275.     { cp->Add(cl); }
  276.     Collection *GetCollection()
  277.     { return cp; }
  278. };
  279.  
  280. void PeClassTreeView::ShowMembers(PeClassItem *ci)
  281. {
  282.     PeCollectClassMembers clm;
  283.     Class *cp= ci->GetClass(), *clp;
  284.     Collection *colItems= new OrdCollection;
  285.     
  286.     cp->EnumerateMyMembers(&clm);
  287.     Iter next(clm.GetCollection());
  288.     while (clp= (Class *)next()) 
  289.     colItems->Add(FindClassItem(clp));
  290.     AddReference (new PeMemberReference(ci, colItems));        
  291. }
  292.  
  293. //---- PeCollectClients ----------------------------------------------------------
  294.  
  295. class PeCollectClients : public AccessMembers {
  296.     Collection *colp;
  297.     Class *clp, *current;
  298. public:
  299.     PeCollectClients(Class *c)
  300.     { colp= new Set; clp= c; }
  301.     ~PeCollectClients()
  302.     { SafeDelete(colp); }
  303.     void SetCurrent(Class *cp)
  304.     { current= cp; }
  305.     void Member(char *, int, int, int, Class *cl, bool, bool)
  306.     { if (clp == cl) colp->Add(current); }
  307.     Collection *GetCollection()
  308.     { return colp; }
  309. };
  310.  
  311. void PeClassTreeView::ShowAllClients(PeClassItem *ci)
  312. {
  313.     Class *cp;
  314.     PeCollectClients clm(ci->GetClass());
  315.     Iter next(gClassManager->Iterator());
  316.     while (cp= (Class*)next()) {
  317.     clm.SetCurrent(cp);
  318.     cp->EnumerateMyMembers(&clm);
  319.     }
  320.     Collection *colItems= new OrdCollection;
  321.     Iter next2(clm.GetCollection());
  322.     while (cp= (Class *)next2()) 
  323.     colItems->Add(FindClassItem(cp));
  324.     AddReference (new PeClassReference(ci, colItems, ePatBlack));        
  325. }
  326.  
  327. PeClassItem *PeClassTreeView::FindClassItem(Class *cp)
  328. {
  329.     PeClassItem dummy(0,cp);
  330.     return (PeClassItem*)classes->Find(&dummy);
  331. }
  332.  
  333. TreeNode *PeClassTreeView::FindTreeNode(VObject *vop)
  334. {
  335.     return (TreeNode*)vop->FindNextHandlerOfClass(Meta(TreeNode));
  336. }
  337.  
  338. //---- NameTreeNodeSelector -------------------------------------------------------------
  339.  
  340. PeNameTreeNodeSelector::PeNameTreeNodeSelector(TreeNode *tn, int cl)
  341. {
  342.     item= tn;
  343.     lastinside= FALSE;
  344.     clicks= cl;
  345.     fp= gFixedFont->WithFace(eFaceBold);
  346.     VObject *vop= tn->At(0)->FindItem(cIdClassItem);
  347.     if (vop && vop->IsKindOf(PeClassItem)) 
  348.     name= ((PeClassItem*)vop)->ClassName();
  349.     p= vop->ContentRect().NE();
  350. }
  351.  
  352. void PeNameTreeNodeSelector::TrackFeedback(Point, Point, bool)
  353. {
  354.     if (item && (lastinside != inside)) {
  355.     GrShowString(fp, ePatXor, p, (byte*) name);
  356.     item->At(0)->Outline(0);
  357.     lastinside= inside;
  358.     }
  359. }
  360.  
  361. Command *PeNameTreeNodeSelector::TrackMouse(TrackPhase atp, Point, Point, Point np)
  362. {
  363.     VObject *image= item->At(0);
  364.     inside= image->ContainsPoint(np);
  365.     if (atp == eTrackRelease) {
  366.     if (item && lastinside) {
  367.         GrShowString(fp, ePatXor, p, (byte*) name);
  368.         image->Outline(0);
  369.         item->GetTreeView()->SetSelection(image);
  370.         return item->GetTreeView()->NodeSelected(item->At(0), clicks);
  371.     }                
  372.     }
  373.     return this; 
  374. }
  375.  
  376. //---- PeClassReference --------------------------------------------------------------------------
  377.  
  378. PeClassReference::PeClassReference(PeClassItem *c, Collection *refs, GrPattern p, int w)
  379. {
  380.     cl= c;
  381.     nodes= refs;
  382.     width= w;
  383.     pat= p;
  384. }
  385.  
  386. PeClassReference::~PeClassReference()
  387. {
  388.     SafeDelete(nodes);
  389. }
  390.  
  391. bool PeClassReference::Includes(PeClassItem *ci)
  392. {
  393.     return nodes->ContainsPtr(ci) || (ci == cl);
  394. }
  395.  
  396. void PeClassReference::Draw(Rectangle)
  397. {
  398.     PeClassItem *clp;
  399.     Iter next(nodes);
  400.  
  401.     if (!cl->IsOpen())
  402.     return;
  403.     GrSetPenNormal();
  404.     GrStrokeRect(cl->contentRect.Expand(1)); 
  405.     while (clp= (PeClassItem*)next()) {
  406.     if (clp->IsOpen()) {
  407.         GrSetPenNormal();
  408.         GrStrokeRect(clp->ContentRect().Expand(1));
  409.         DrawConnection(cl, clp);
  410.     }
  411.     }
  412. }
  413.  
  414. void PeClassReference::DrawConnection(PeClassItem *from, PeClassItem *to)
  415. {
  416.     GrMoveto(from->contentRect.Center());
  417.     GrSetPenSize(1);
  418.     SetWidthAndPattern(from, to);
  419.     
  420.     if (from == to) 
  421.     CircularReference(from);
  422.     else {
  423.     GrMoveto(from->contentRect.Center());
  424.     GrLineto(to->contentRect.Center());
  425.     }
  426. }
  427.  
  428. static RGBColor *c2;
  429.  
  430. void PeClassReference::SetWidthAndPattern(PeClassItem*, PeClassItem*)
  431. {
  432.     if (c2 == 0)
  433.     c2= new_RGBColor(0, 256, 0);
  434.     GrSetPenSize(width);
  435.     GrSetPenInk(c2);
  436. }
  437.  
  438. void PeClassReference::CircularReference(PeClassItem *ci)
  439. {
  440.     int d= ci->ContentRect().Height();
  441.     Rectangle rr(ci->ContentRect().NE()-Point(d/2), Point(d)); 
  442.     GrStrokeOval(rr);
  443. }
  444.  
  445. Rectangle PeClassReference::BBox()
  446. {
  447.     Rectangle r;
  448.     VObject *clp;
  449.     Iter next(nodes);
  450.   
  451.     r= cl->ContentRect().Expand(20);
  452.     while ((clp= (VObject *)next())) 
  453.     r.Merge(clp->ContentRect().Expand(4));
  454.     return r;
  455. }
  456.  
  457. //---- PeMemberReference ---------------------------------------------------------
  458.  
  459. PeMemberReference::PeMemberReference(PeClassItem *cl, Collection *n) : 
  460.                                PeClassReference(cl, n)
  461. {
  462. }
  463.  
  464. void PeMemberReference::SetWidthAndPattern(PeClassItem*, PeClassItem*)
  465. {
  466.     if (c1 == 0)
  467.     c1= new RGBColor(256, 0, 0);
  468.     GrSetPenInk(c1);
  469. }
  470.  
  471. //---- PeHierarchyBrowser --------------------------------------------------------
  472.  
  473. NewMetaImpl(PeHierarchyBrowser,EtPeTool, (TP(ct)));
  474.  
  475. PeHierarchyBrowser *PeHierarchyBrowser::hierBrowser;
  476.  
  477. PeHierarchyBrowser::PeHierarchyBrowser(Manager *m, Class *root)
  478.                         : EtPeTool(m, "Class Hierarchy")
  479. {
  480.     ct= new PeClassTreeView(this, root);
  481. }
  482.  
  483. VObject *PeHierarchyBrowser::DoMakeContent()
  484. {
  485.     hierZoomer= new Zoomer(ct);
  486.     hierZoomer->SetBgInk(gInkNone);
  487.     SetFirstHandler(ct);
  488.     return new VExpander(gPoint5,
  489.     hierZoomer,
  490.     0
  491.     );
  492. }
  493.  
  494. Point PeHierarchyBrowser::GetInitialWindowSize()
  495. {
  496.     return Point(600,600);
  497. }
  498.  
  499. PeHierarchyBrowser::~PeHierarchyBrowser()
  500. {
  501.     SafeDelete(ct);
  502. }
  503.  
  504. MenuBar *PeHierarchyBrowser::DoMakeMenuBar()
  505. {
  506.     MenuBar *mb= EtPeTool::DoMakeMenuBar();
  507.     
  508.     Menu *m= Zoomer::MakeMenu(cVIEWMENU);
  509.     m->InsertItemsBefore(cZOOMOUT,
  510.             "Tree",                    cTREEVIEW,
  511.             "Outline",                 cOUTLINEVIEW,
  512.             "-",
  513.             "All Classes",             cALLCLASSES,
  514.             "Abstract Classes",        cONLYABSTRACT,
  515.             "Application Classes",     cONLYAPPL,
  516.             "-",
  517.             0);                      
  518.     mb->AddMenu(m);
  519.  
  520.     m= new Menu("Classes");
  521.     m->AppendItems(
  522.             "Members",                  cMEMBERS,
  523.             "Clients",                  cCLIENTS,
  524.             "Show Source",              cSOURCE,
  525.             "-",
  526.             "Clear Lines",              cCLEARREFS,
  527.             "-",
  528.             "Collapse",                 cDOCOLLAPSE,
  529.             "Promote",                  cPROMOTE,
  530.             0);  
  531.     mb->AddMenu(m);
  532.                         
  533.     return mb;
  534. }
  535.  
  536. void PeHierarchyBrowser::DoSetupMenu(Menu *mp)
  537. {
  538.     EtPeTool::DoSetupMenu(mp);
  539.     Clipper *vf= hierZoomer->GetClipper();
  540.     if (vf->GetZoom() < 1024)
  541.     mp->EnableItem(cZOOMIN);
  542.     if (vf->GetZoom() > 0.01)
  543.     mp->EnableItem(cZOOMOUT);
  544.     
  545.     mp->EnableItems(cZOOMRESET, cTREEVIEW, cOUTLINEVIEW, 0);
  546.     mp->CheckItem(cOUTLINEVIEW, ct->GetLayout() == eTLIndented);
  547.     mp->CheckItem(cTREEVIEW, ct->GetLayout() == eTLLeftRight);
  548.     
  549.     mp->CheckItem(cALLCLASSES, ct->Shows() == ePeCTShowAll);
  550.     mp->CheckItem(cONLYABSTRACT, ct->Shows() == ePeCTShowAbstract);
  551.     mp->CheckItem(cONLYAPPL, ct->Shows() == ePeCTShowApp);
  552.     
  553.     mp->EnableItems(cMEMBERS, cCLIENTS, cSOURCE, cDOCOLLAPSE, cCLEARREFS,
  554.             cALLCLASSES, cONLYABSTRACT, cONLYAPPL, cPROMOTE, 0);
  555. }
  556.  
  557. Command *PeHierarchyBrowser::DoMenuCommand(int cmd)
  558. {
  559.     Clipper *vf= hierZoomer->GetClipper();
  560.     switch (cmd) {
  561.     case cZOOMOUT: 
  562.     vf->SetZoom(vf->GetZoom()/1.2);
  563.     break;
  564.     
  565.     case cZOOMIN:
  566.     vf->SetZoom(vf->GetZoom()*1.2);
  567.     break;
  568.     
  569.     case cZOOMRESET:
  570.     vf->SetZoom(1.0);
  571.     break;
  572.     
  573.     case cONLYABSTRACT:
  574.     ct->ShowOnlyAbstractClasses();
  575.     break;
  576.     
  577.     case cONLYAPPL:
  578.     ct->ShowOnlyApplicationClasses();
  579.     break;
  580.     
  581.     case cALLCLASSES:
  582.     ct->ShowAllClasses();
  583.     break; 
  584.     
  585.     case cCLEARREFS:
  586.     ct->RemoveAllReferences();
  587.     break;
  588.     
  589.     default:
  590.     return EtPeTool::DoMenuCommand(cmd);
  591.     }
  592.     return gNoChanges;
  593. }
  594.  
  595. void PeHierarchyBrowser::ShowClass(Class *cp)
  596. {
  597.     ct->ShowClass(cp);
  598. }
  599.   
  600. void PeHierarchyBrowser::Spawn(Manager *m, Class *root)
  601. {
  602.     PeHierarchyBrowser *hb= new PeHierarchyBrowser(m, root);
  603.     hb->SetOnDismiss(eMgrClose);
  604.     hb->Show();
  605. }
  606.  
  607. void PeHierarchyBrowser::ShowClass(Manager *m, Class *selection)
  608. {
  609.     if (hierBrowser == 0)
  610.     hierBrowser= new PeHierarchyBrowser(m, gClassManager->Find("Object"));
  611.     hierBrowser->Show();
  612.     hierBrowser->ShowClass(selection); 
  613. }
  614.  
  615.